#include <stdio.h>
#include "bootpack.h"

extern struct KEYBUF keybuf;

void HariMain(void)
{
	struct BOOTINFO *binfo = (struct BOOTINFO *)0x0ff0;
	char s[40], mcursor[256];
	int mx, my, i, j;

	init_gdtidt();
	init_pic();
	io_sti(); /* 由于IDT/PIC初始化已完成，因此CPU中断被禁用。 */

	/* 修改IMR（中断屏蔽寄存器），如果某一位的值是1，则该位所对应的IRO信号被屏蔽,PIC就忽视该路信号 */
	io_out8(PIC0_IMR, 0xf9); /* 允许PIC1和键盘（11111001） */
	io_out8(PIC1_IMR, 0xef); /* 允许鼠标（11101111） */

	init_palette();
	init_screen8(binfo->vram, binfo->scrnx, binfo->scrny);
	mx = (binfo->scrnx - 16) / 2; /* 屏幕中心坐标计算 */
	my = (binfo->scrny - 28 - 16) / 2;
	init_mouse_cursor8(mcursor, COL8_008484);
	putblock8_8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16);
	sprintf(s, "(%d, %d)", mx, my);
	putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s);

	for (;;)
	{
		io_cli();			  /* 先屏蔽中断 */
		if (keybuf.next == 0) /* next == 0 说明键还没有按下 */
		{					  /* 只执行hlt暂停的话会收不到PIC，所以STI和HLT都要执行，收到PIC通知，CPU就会被唤醒 */
			io_stihlt();
		}
		else
		{
			i = keybuf.data[0]; /* 队首元素拿出来 */
			keybuf.next--;		/* 计数-1 */
			for (j = 0; j < keybuf.next; j++)
			{
				keybuf.data[j] = keybuf.data[j + 1]; /* 所有元素前移一个 */
			}
			io_sti(); /* 开放中断，不怕再有中断进来造成混乱，就可以再中断开放的情况下安心显示字符了 */
			sprintf(s, "%02X", i);
			boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31);
			putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s);
		}
	}
}